package com.ljt.system.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ljt.system.entity.Menu;
import com.ljt.system.entity.Role;
import com.ljt.system.entity.User;
import com.ljt.system.mapper.MenuMapper;
import com.ljt.system.mapper.RoleMapper;
import com.ljt.system.mapper.UserMapper;
import com.ljt.system.service.UserService;
import com.ljt.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author ljt
 * @since 2021-06-27
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private MenuMapper menuMapper;


    @Autowired
    private RedisUtil redisUtil;

    /**
     * 根据用户编号获取用户的权限信息
     *
     * @param id
     * @return
     */
    @Override
    public String getUserAuthorityInfo(Long id) {
        // 根据编号获取用户信息
        User user = this.baseMapper.selectById(id);
        // 用于接收用户信息拼接的字符串以“，” 拼接
        String authority = "";

        // 判断是redis中是否存在该用户的权限
        if (redisUtil.hasKey("GrantedAuthority" + user.getUsername())) {
            // 如果有直接取出
            authority = (String) redisUtil.get("GrantedAuthority" + user.getUsername());
        } else {
            // 获取用户所有的角色
            List<Role> roles = roleMapper.queryRolesByUserId(id);
            // 判断是否存在权限
            if (roles.size() > 0) {
                // 循环将权限信息用“，”拼接
                String roleNames = roles.stream().map(r -> "ROLE_" + r.getRoleName())
                        .collect(Collectors.joining(","));
                authority = roleNames.concat(",");
            }
            // 获取用户所有的菜单
            List<Menu> menus = menuMapper.queryMenusByUserId(id);
            // 判断是否存在菜单信息
            if (menus.size() > 0) {
                // 循环将菜单信息用“,"拼接
                String menuNames = menus.stream().map(m -> m.getPerms()).collect(Collectors.joining(","));
                authority = authority.concat(menuNames);
            }
            // 将用户的权限存放到redis中设置过期时间为1天
            redisUtil.set("GrantedAuthority" + user.getUsername(), authority, 60 * 60 * 24);
        }

        // 返回用户权限信息字符串
        return authority;
    }

    /**
     * 根据用户名删除redis中对应的权限信息
     *
     * @param username 用户名
     */
    @Override
    public void clearUserAuthorityByUsername(String username) {
        // 删除redis中对应用户名的权限信息
        redisUtil.del("GrantedAuthority" + username);
    }

    /**
     * 根据权限编号删除redis中对应用户的权限信息
     *
     * @param roleId 权限编号
     */
    @Override
    public void clearUserAuthorityByRoleId(Long roleId) {
        // 获取该角色对应的所有用户信息
        List<User> users = this.baseMapper.queryUserByRoleId(roleId);
        // 循环将该用户存放到redis中的权限新删除
        users.forEach(u -> {
            this.clearUserAuthorityByUsername(u.getUsername());
        });
    }

    /**
     * @param menuId
     */
    @Override
    public void clearUserAuthorityByMenuId(Long menuId) {
        List<User> users = this.baseMapper.queryUserByMenuId(menuId);
        // 循环将该用户存放到redis中的权限新删除
        users.forEach(u -> {
            this.clearUserAuthorityByUsername(u.getUsername());
        });
    }
}
